package com.example.commonUpAndDownFileutil.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import static org.springframework.util.FileCopyUtils.BUFFER_SIZE;

/**
 * 直接下载
 *
 *
 */
@RestController
@RequestMapping("/api/upload")
public class UploadController {
    // 上传文件保存路径
    private static final String UPLOAD_DIR = "uploads/";

    // 允许的文件类型
    private static final List<String> ALLOWED_CONTENT_TYPES = List.of(
            "image/jpeg", "image/png", "image/gif",
            "application/pdf", "application/msword",
            "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
            "text/plain"  // 新增TXT文件类型
    );

    // 最大文件大小 10MB
    private static final long MAX_FILE_SIZE = 100 * 1024 * 1024;

    private ResponseEntity<?> checkInput(MultipartFile file) {
        // 验证文件是否为空
        if (file.isEmpty()) {
            return ResponseEntity.badRequest().body("上传的文件不能为空");
        }

        // 验证文件大小
        if (file.getSize() > MAX_FILE_SIZE) {
            return ResponseEntity.badRequest().body("文件大小不能超过10MB");
        }

        // 验证文件类型
        if (!ALLOWED_CONTENT_TYPES.contains(file.getContentType())) {
            return ResponseEntity.badRequest().body("不支持的文件类型");
        }
        // 确保上传目录存在
        createUploadDirIfNotExists();
        return null;
    }

    @PostMapping("/single1")
    public ResponseEntity<?> uploadSingleFile1(@RequestParam("file") MultipartFile file) {
        try {
            // 验证文件是否为空
            ResponseEntity<?> inputResult = checkInput(file);
            if (inputResult != null) {
                return inputResult;
            }

            // 生成唯一文件名，避免覆盖
            String originalFilename = file.getOriginalFilename();
            String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String uniqueFileName = UUID.randomUUID() + fileExtension;

            // 保存文件
            Path path = Paths.get(UPLOAD_DIR + uniqueFileName);
            Files.write(path, file.getBytes());

            // 返回成功信息
            return ResponseEntity.ok().body("文件上传成功: " + uniqueFileName);

        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("文件上传失败: " + e.getMessage());
        }
    }

    @PostMapping("/single2")
    public ResponseEntity<?> uploadSingleFile2(@RequestParam("file") MultipartFile file) {
        try {
            // 验证文件是否为空
            ResponseEntity<?> inputResult = checkInput(file);
            if (inputResult != null) {
                return inputResult;
            }

            // 生成唯一文件名，避免覆盖
            String originalFilename = file.getOriginalFilename();
            String fileExtension = getFileExtension(originalFilename);
            String uniqueFileName = UUID.randomUUID().toString() + fileExtension;

            // 使用缓冲流保存文件（优化点）
            Path path = Paths.get(UPLOAD_DIR + uniqueFileName);
            try (InputStream inputStream = file.getInputStream();
                 BufferedInputStream bis = new BufferedInputStream(inputStream);
                 BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(path))) {

                byte[] buffer = new byte[BUFFER_SIZE];
                int bytesRead;
                // 分块读取并写入文件
                while ((bytesRead = bis.read(buffer)) != -1) {
                    bos.write(buffer, 0, bytesRead);
                }
            }

            // 返回成功信息
            return ResponseEntity.ok().body("文件上传成功: " + uniqueFileName);

        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("文件上传失败: " + e.getMessage());
        }
    }

    @PostMapping("/multiple1")
    public ResponseEntity<?> uploadMultipleFiles1(@RequestParam("files") MultipartFile[] files) {
        List<String> uploadedFiles = new ArrayList<>();
        List<String> errorMessages = new ArrayList<>();

        if (files == null || files.length == 0) {
            return ResponseEntity.badRequest().body("请选择要上传的文件");
        }

        // 确保上传目录存在
        createUploadDirIfNotExists();

        for (MultipartFile file : files) {
            try {
                // 验证文件是否为空
                if (file.isEmpty()) {
                    errorMessages.add("一个空文件被跳过");
                    continue;
                }

                // 验证文件大小
                if (file.getSize() > MAX_FILE_SIZE) {
                    errorMessages.add("文件 " + file.getOriginalFilename() + " 大小超过限制(10MB)");
                    continue;
                }

                // 验证文件类型
                if (!ALLOWED_CONTENT_TYPES.contains(file.getContentType())) {
                    errorMessages.add("文件 " + file.getOriginalFilename() + " 类型不支持");
                    continue;
                }

                // 生成唯一文件名
                String originalFilename = file.getOriginalFilename();
                String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
                String uniqueFileName = UUID.randomUUID().toString() + fileExtension;

                // 保存文件
                Path path = Paths.get(UPLOAD_DIR + uniqueFileName);
                Files.write(path, file.getBytes());

                uploadedFiles.add(uniqueFileName);

            } catch (IOException e) {
                errorMessages.add("文件 " + file.getOriginalFilename() + " 上传失败: " + e.getMessage());
            }
        }

        // 构建响应结果
        UploadResult result = new UploadResult();
        result.setSuccessfullyUploaded(uploadedFiles);
        result.setErrors(errorMessages);

        if (uploadedFiles.isEmpty() && !errorMessages.isEmpty()) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
        }

        return ResponseEntity.ok().body(result);
    }

    @PostMapping("/multiple2")
    public ResponseEntity<?> uploadMultipleFiles2(@RequestParam("files") MultipartFile[] files) {
        List<String> uploadedFiles = new ArrayList<>();
        List<String> errorMessages = new ArrayList<>();

        if (files == null || files.length == 0) {
            return ResponseEntity.badRequest().body("请选择要上传的文件");
        }

        // 确保上传目录存在
        createUploadDirIfNotExists();

        for (MultipartFile file : files) {
            try {
                // 验证文件是否为空
                if (file.isEmpty()) {
                    errorMessages.add("一个空文件被跳过");
                    continue;
                }

                // 验证文件大小
                if (file.getSize() > MAX_FILE_SIZE) {
                    errorMessages.add("文件 " + file.getOriginalFilename() + " 大小超过限制(100MB)");
                    continue;
                }

                // 验证文件类型
                if (!ALLOWED_CONTENT_TYPES.contains(file.getContentType())) {
                    errorMessages.add("文件 " + file.getOriginalFilename() + " 类型不支持");
                    continue;
                }

                // 生成唯一文件名
                String originalFilename = file.getOriginalFilename();
                String fileExtension = getFileExtension(originalFilename);
                String uniqueFileName = UUID.randomUUID().toString() + fileExtension;

                // 使用缓冲流保存文件（优化点）
                Path path = Paths.get(UPLOAD_DIR + uniqueFileName);
                try (InputStream inputStream = file.getInputStream();
                     BufferedInputStream bis = new BufferedInputStream(inputStream);
                     BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(path))) {

                    byte[] buffer = new byte[BUFFER_SIZE];
                    int bytesRead;
                    // 分块读取并写入文件
                    while ((bytesRead = bis.read(buffer)) != -1) {
                        bos.write(buffer, 0, bytesRead);
                    }
                }

                uploadedFiles.add(uniqueFileName);

            } catch (IOException e) {
                errorMessages.add("文件 " + file.getOriginalFilename() + " 上传失败: " + e.getMessage());
            }
        }

        // 构建响应结果
        UploadResult result = new UploadResult();
        result.setSuccessfullyUploaded(uploadedFiles);
        result.setErrors(errorMessages);

        if (uploadedFiles.isEmpty() && !errorMessages.isEmpty()) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
        }

        return ResponseEntity.ok().body(result);
    }

    // 提取文件扩展名的工具方法
    private String getFileExtension(String originalFilename) {
        if (originalFilename == null || !originalFilename.contains(".")) {
            return "";
        }
        return originalFilename.substring(originalFilename.lastIndexOf("."));
    }

    // 创建上传目录（如果不存在）
    private void createUploadDirIfNotExists() {
        File uploadDir = new File(UPLOAD_DIR);
        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }
    }

    // 内部类，用于多文件上传结果
    private static class UploadResult {
        private List<String> successfullyUploaded;
        private List<String> errors;

        // Getters and Setters
        public List<String> getSuccessfullyUploaded() {
            return successfullyUploaded;
        }

        public void setSuccessfullyUploaded(List<String> successfullyUploaded) {
            this.successfullyUploaded = successfullyUploaded;
        }

        public List<String> getErrors() {
            return errors;
        }

        public void setErrors(List<String> errors) {
            this.errors = errors;
        }
    }
}
